package main

// 31. 下一个排列
func main() {
	nums := []int{1, 2, 4, 7, 6, 5, 3}
	//nums := []int{1, 1, 5}
	nextPermutation(nums)
	for _, i := range nums {
		print(i)
	}
}

func nextPermutation(nums []int) {
	numLen := len(nums)
	idx := numLen - 2 // 从后往前，第一个倒序的值，如果不是第一个，那就是-1
	for i := numLen - 1; i > 0; i-- {
		if nums[i] > nums[i-1] {
			break
		}
		idx--
	}
	if idx == -1 { // 已是最大倒序排列
		reverseArr(nums, 0, numLen-1)
		return
	}

	flagNum := nums[idx]
	rightIdx := idx

	for i := idx; i < numLen-1 && flagNum < nums[i+1]; i++ {
		rightIdx++
	}
	nums[rightIdx], nums[idx] = nums[idx], nums[rightIdx]

	reverseArr(nums, idx+1, numLen-1)
}

func reverseArr(nums []int, leftIdx, rightIdx int) {
	mid := (rightIdx - leftIdx) / 2
	for i := 0; i <= mid; i++ {
		nums[leftIdx+i], nums[rightIdx-i] = nums[rightIdx-i], nums[leftIdx+i]
	}
}

// 整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。
//
//例如，arr = [1,2,3] ，以下这些都可以视作 arr 的排列：[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
//整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地，如果数组的所有排列根据其字典顺序从小到大排列在一个容器中，那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列，那么这个数组必须重排为字典序最小的排列（即，其元素按升序排列）。
//
//例如，arr = [1,2,3] 的下一个排列是 [1,3,2] 。
//类似地，arr = [2,3,1] 的下一个排列是 [3,1,2] 。
//而 arr = [3,2,1] 的下一个排列是 [1,2,3] ，因为 [3,2,1] 不存在一个字典序更大的排列。
//给你一个整数数组 nums ，找出 nums 的下一个排列。
//
//必须 原地 修改，只允许使用额外常数空间。
//
//
//
//示例 1：
//
//输入：nums = [1,2,3]
//输出：[1,3,2]
//示例 2：
//
//输入：nums = [3,2,1]
//输出：[1,2,3]
//示例 3：
//
//输入：nums = [1,1,5]
//输出：[1,5,1]
//
//
//提示：
//
//1 <= nums.length <= 100
//0 <= nums[i] <= 100
